home *** CD-ROM | disk | FTP | other *** search
/ Programming a Multiplayer FPS in DirectX / Programming a Multiplayer FPS in DirectX (Companion CD).iso / DirectX / dxsdk_oct2004.exe / dxsdk.exe / Utilities / Content Creation Tool Plug-Ins / Maya / Sources / device.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2004-09-27  |  8.9 KB  |  272 lines

  1. #include "dxstdafx.h"
  2. #include "PreviewPipeline.h"
  3. #include "XExporter.h"
  4. #include "device.h"
  5. #include <process.h>
  6.  
  7. //-------------------------------------------------------------------------------------
  8. UINT __stdcall CEngine::StaticRunThread( void* pParam )
  9. {
  10.     CEngine* pDevice = (CEngine*) pParam;
  11.     return pDevice->RunThread();
  12. }
  13.  
  14.  
  15. //-------------------------------------------------------------------------------------
  16. UINT __stdcall CEngine::RunThread()
  17. {
  18.     EnterCriticalSection(&DeviceAndViewerSection);
  19.           
  20.     HRESULT hr;
  21.  
  22.     IDirect3D9* pD3D = DXUTGetD3DObject();
  23.     if( pD3D == NULL )
  24.     {
  25.         V_RETURN( DXUTInit( false, false, false ) );
  26.         pD3D = DXUTGetD3DObject();
  27.     }
  28.  
  29.     // Create a device window
  30.     m_hwndFocus = CreateWindow( L"STATIC", L"D3D Device Window", WS_POPUP, 0, 0, 1, 1, NULL, NULL, NULL, NULL );
  31.  
  32.     // Enumerate for each adapter all of the supported display modes, 
  33.     // device types, adapter formats, back buffer formats, window/full screen support, 
  34.     // depth stencil formats, multisampling types/qualities, and presentations intervals.
  35.     //
  36.     // For each combination of device type (HAL/REF), adapter format, back buffer format, and
  37.     // IsWindowed it will call the app's ConfirmDevice callback.  This allows the app
  38.     // to reject or allow that combination based on its caps/etc.  It also allows the 
  39.     // app to change the BehaviorFlags.  The BehaviorFlags defaults non-pure HWVP 
  40.     // if supported otherwise it will default to SWVP, however the app can change this 
  41.     // through the ConfirmDevice callback.
  42.     CD3DEnumeration* pd3dEnum; 
  43.     pd3dEnum = DXUTGetEnumeration();
  44.     V( pd3dEnum->Enumerate( pD3D, IsDeviceAcceptable ) );
  45.     if( FAILED(hr) )
  46.         goto LCleanReturn;
  47.     
  48.     DXUTMatchOptions matchOptions;
  49.     matchOptions.eAdapterOrdinal     = DXUTMT_PRESERVE_INPUT;
  50.     matchOptions.eDeviceType         = DXUTMT_IGNORE_INPUT;
  51.     matchOptions.eWindowed           = DXUTMT_PRESERVE_INPUT;
  52.     matchOptions.eAdapterFormat      = DXUTMT_IGNORE_INPUT;
  53.     matchOptions.eVertexProcessing   = DXUTMT_IGNORE_INPUT;
  54.     matchOptions.eResolution         = DXUTMT_CLOSEST_TO_INPUT;
  55.     matchOptions.eBackBufferFormat   = DXUTMT_IGNORE_INPUT;
  56.     matchOptions.eBackBufferCount    = DXUTMT_IGNORE_INPUT;
  57.     matchOptions.eMultiSample        = DXUTMT_IGNORE_INPUT;
  58.     matchOptions.eSwapEffect         = DXUTMT_IGNORE_INPUT;
  59.     matchOptions.eDepthFormat        = DXUTMT_IGNORE_INPUT;
  60.     matchOptions.eStencilFormat      = DXUTMT_IGNORE_INPUT;
  61.     matchOptions.ePresentFlags       = DXUTMT_IGNORE_INPUT;
  62.     matchOptions.eRefreshRate        = DXUTMT_IGNORE_INPUT;
  63.     matchOptions.ePresentInterval    = DXUTMT_IGNORE_INPUT;
  64.  
  65.     DXUTDeviceSettings deviceSettings;
  66.     ZeroMemory( &deviceSettings, sizeof(DXUTDeviceSettings) );
  67.     deviceSettings.AdapterOrdinal      = D3DADAPTER_DEFAULT;
  68.     deviceSettings.pp.Windowed         = true;
  69.     deviceSettings.pp.EnableAutoDepthStencil = false;
  70.     
  71.     deviceSettings.pp.BackBufferWidth  = 1;
  72.     deviceSettings.pp.BackBufferHeight = 1;
  73.     
  74.     hr = DXUTFindValidDeviceSettings( &deviceSettings, &deviceSettings, &matchOptions );
  75.     if( FAILED(hr) ) // the call will fail if no valid devices were found
  76.     {
  77.         DXUT_ERR( L"DXUTFindValidDeviceSettings", hr );
  78.         goto LCleanReturn;
  79.     }
  80.  
  81.     D3DCAPS9 caps;
  82.     pD3D->GetDeviceCaps( deviceSettings.AdapterOrdinal, deviceSettings.DeviceType, &caps );
  83.     ModifyDeviceSettings( &deviceSettings, &caps );
  84.  
  85.     hr = pD3D->CreateDevice( deviceSettings.AdapterOrdinal, deviceSettings.DeviceType, 
  86.                              m_hwndFocus, deviceSettings.BehaviorFlags,
  87.                              &deviceSettings.pp, &m_pd3dDevice );
  88.     if( FAILED(hr) )
  89.     {
  90.         DXUT_ERR( L"CreateDevice", hr );
  91.         goto LCleanReturn;
  92.     }
  93.  
  94.     m_pPreviewPipeline->TriggerDeviceEvents.OnD3DDeviceCreate();
  95.     m_pPreviewPipeline->TriggerDeviceEvents.OnD3DDeviceReset();
  96.  
  97.  
  98.     LeaveCriticalSection(&DeviceAndViewerSection);
  99.     SetEvent(DeviceCreatedEvent);
  100.  
  101.  
  102.     while( m_bDestroyCalled == false )
  103.     {
  104.         bool bTriggerLostEvent= false;
  105.         CPipelineLock Lock;
  106.         if(m_pPreviewPipeline->SceneWriteLock(false, Lock))
  107.         {
  108.             // Test the cooperative level to see if it's okay to render
  109.             if( D3DERR_DEVICENOTRESET == m_pd3dDevice->TestCooperativeLevel() )
  110.             {
  111.                 bTriggerLostEvent= true;
  112.             }
  113.             m_pPreviewPipeline->SceneWriteUnlock(Lock);
  114.         }
  115.         if(bTriggerLostEvent)
  116.         {
  117.             m_pPreviewPipeline->TriggerDeviceEvents.OnD3DDeviceLost();
  118.  
  119.             m_pPreviewPipeline->SceneWriteLock(true, Lock);
  120.             {
  121.                 V( m_pd3dDevice->Reset( &deviceSettings.pp ) );
  122.                 if( FAILED(hr) && D3DERR_DEVICELOST != hr )  
  123.                 {
  124.                     DXUT_ERR( L"pd3dDevice->Reset", hr ); 
  125.                     goto LCleanReturn;
  126.                 }
  127.             }
  128.             m_pPreviewPipeline->SceneWriteUnlock(Lock);
  129.  
  130.             m_pPreviewPipeline->TriggerDeviceEvents.OnD3DDeviceReset();
  131.         }
  132.  
  133.         if(m_bDestroyCalled == false)
  134.             Sleep( 1000 );
  135.     }
  136.  
  137.     hr = S_OK;
  138.  
  139. LCleanReturn:
  140.     m_pPreviewPipeline->TriggerDeviceEvents.OnD3DDeviceDestroy();
  141.     SAFE_RELEASE( m_pd3dDevice );
  142.     DXUTShutdown();
  143.  
  144.     return hr;
  145. }
  146.  
  147.  
  148. //-------------------------------------------------------------------------------------
  149. HRESULT CEngine::Create( CPipeline* pPreviewPipeline )
  150. {
  151.     // Start clean
  152.     Destroy();
  153.     m_bDestroyCalled = false;
  154.  
  155.     m_pPreviewPipeline = pPreviewPipeline;
  156.  
  157.     // Launch the thread which will create the device and check for device state changes
  158.     m_hThread = _beginthreadex( NULL, 0, StaticRunThread, this, 0, &m_nThreadID );
  159.     if( m_hThread == NULL )
  160.         return E_FAIL;
  161.  
  162.     GetSingleObject(true, DeviceCreatedEvent);
  163.  
  164.     return S_OK;
  165. }
  166.  
  167.  
  168. //-------------------------------------------------------------------------------------
  169. HRESULT CEngine::Destroy()
  170. {
  171.     m_bDestroyCalled = true;
  172.  
  173.     WaitForSingleObject( (HANDLE)m_hThread, INFINITE );
  174.     TerminateThread((HANDLE)m_hThread, 0);
  175.     CloseHandle( (HANDLE)m_hThread );
  176.  
  177.     DestroyWindow( m_hwndFocus );
  178.     m_hwndFocus = NULL;
  179.     m_hThread = 0;
  180.     m_nThreadID = 0;
  181.  
  182.  
  183.  
  184.     m_bDestroyCalled = false;
  185.  
  186.  
  187.  
  188.     return S_OK;
  189. }
  190.  
  191.  
  192. //-------------------------------------------------------------------------------------
  193. HRESULT CEngine::GetD3DObject( IDirect3D9** ppObject )
  194. {
  195.     IDirect3D9* pd3d = DXUTGetD3DObject();
  196.     if( pd3d == NULL )
  197.         return E_FAIL;
  198.  
  199.     pd3d->AddRef();
  200.     *ppObject = pd3d;
  201.  
  202.     return S_OK;
  203. }
  204.  
  205.  
  206. //-------------------------------------------------------------------------------------
  207. HRESULT CEngine::GetD3DDevice( IDirect3DDevice9** ppDevice )
  208. {
  209.     if( m_pd3dDevice == NULL )
  210.         return E_FAIL;
  211.  
  212.     m_pd3dDevice->AddRef();
  213.     *ppDevice = m_pd3dDevice;
  214.  
  215.     return S_OK;
  216. }
  217.  
  218.  
  219. //-------------------------------------------------------------------------------------
  220. bool CALLBACK CEngine::IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, bool bWindowed )
  221. {
  222.     // No fallback defined by this app, so reject any device that 
  223.     // doesn't support at least ps1.1
  224.     if( pCaps->PixelShaderVersion < D3DPS_VERSION(1,1) )
  225.         return false;
  226.  
  227.     return true;
  228. }
  229.  
  230.  
  231. //-------------------------------------------------------------------------------------
  232. void CALLBACK CEngine::ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps )
  233. {
  234.     // If device doesn't support HW T&L or doesn't support 1.1 vertex shaders in HW 
  235.     // then switch to SWVP.
  236.     if( (pCaps->DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) == 0 ||
  237.          pCaps->VertexShaderVersion < D3DVS_VERSION(1,1) )
  238.     {
  239.         pDeviceSettings->BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
  240.     }
  241.     else
  242.     {
  243.         pDeviceSettings->BehaviorFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
  244.     }
  245.  
  246.     // This application is designed to work on a pure device by not using 
  247.     // IDirect3D9::Get*() methods, so create a pure device if supported and using HWVP.
  248.     if ((pCaps->DevCaps & D3DDEVCAPS_PUREDEVICE) != 0 && 
  249.         (pDeviceSettings->BehaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING) != 0 )
  250.         pDeviceSettings->BehaviorFlags |= D3DCREATE_PUREDEVICE;
  251.  
  252.     // Debugging vertex shaders requires either REF or software vertex processing 
  253.     // and debugging pixel shaders requires REF.  
  254. #ifdef DEBUG_VS
  255.     if( pDeviceSettings->DeviceType != D3DDEVTYPE_REF )
  256.     {
  257.         pDeviceSettings->BehaviorFlags &= ~D3DCREATE_HARDWARE_VERTEXPROCESSING;
  258.         pDeviceSettings->BehaviorFlags &= ~D3DCREATE_PUREDEVICE;                            
  259.         pDeviceSettings->BehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
  260.     }
  261. #endif
  262. #ifdef DEBUG_PS
  263.     pDeviceSettings->DeviceType = D3DDEVTYPE_REF;
  264. #endif
  265.  
  266.     // Force multithreaded
  267.     pDeviceSettings->BehaviorFlags |= D3DCREATE_MULTITHREADED;
  268. }
  269.  
  270.  
  271.  
  272.